﻿using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
//********** 修正开始 **********//
using UnityEngine.UI; // 使用UI依赖
					  //********** 修正结束 **********//

using System.Collections.Generic; //引用C#的List功能

public class GameManager : MonoBehaviour
{

	//********** 修正开始 **********//
	public float levelStartDelay = 2f; //level显示画面持续2秒
									   //********** 修正结束 **********//

	public float turnDelay = .1f; //Enemy的动作耗时(0.1秒)

	//static变量：程序/场景之间共享
	//游戏中单独的变量
	//不由游戏对象所属，由程序控制所属
	public static GameManager instance = null;

	public BoardManager boardScript;

	public int playerFoodPoints = 100; //Player的体力
	public int playerBombPoints = 10;
	//HideInInspector: 修饰public变量但是无法让Inspector操作 与 [SerializeField]相反
	//Player回合判定

	[HideInInspector] public bool playersTurn = true;

	private List<Enemy> enemies; //Enemy序列
	private bool enemiesMoving; //Enemy的回合中是true

	//********** 修正开始 **********//
	private Text levelText; //level文本
	private GameObject levelImage; //level背景图片
	private int level = 1; //level初始化设置成1

	// 初始化执行中的flag（黑色的UI显示的时候用来禁止玩家/敌人的活动）
	// levelImage.activeSelf直接代理这个flag感觉更清爽
	private bool doingSetup;

	//********** 修正结束 **********//

	//Awake : Scene被打开时最先被执行
	void Awake()
	{

		//********** 改造开始 **********// 
		//游戏开始时GameManager指定到instance里
		if (instance == null)
		{
			instance = this;
			//如果这个对象之外还有别的GameManager的时候销毁自己
			//类的实例和类的实例进行判断 如果不是自身，就把自身销毁
		}
		else if (instance != this)
		{
			//销毁
			Destroy(gameObject);
		}
		//场景迁移的时候保留当前对象
		//读取场景的时候禁止销毁自己
		DontDestroyOnLoad(gameObject);

		// 例：
		// SceneManager.LoadScene("sub");
		// 执行之后GameManager实例的游戏对象还存在，不会被因为进入了一个新场景而销毁

		//生成容纳Enemy的序列
		enemies = new List<Enemy>();

		//获取BoardManager
		boardScript = GetComponent<BoardManager>();
		//初始化游戏
		InitGame();

	}

	//********** 修正开始 **********//
	//利用Unity的生命周期API、每当运行Scene时会被执行的方法
	private void OnLevelWasLoaded(int index)
	{

		// 读取当前关卡 （Unity2017之后）
		// 执行在之后立即发生
		// SceneManager.LoadScene(SceneManager.GetActiveScene().name);
		// 此处的index是build setting里设置场景的索引
		// 可以根据关卡尽心判断 我们做一些特殊操作

		level++; //level设置成1
		InitGame();
	}
	//********** 修正结束 **********//

	void InitGame()
	{

		//********** 修正开始 **********//
		//true的时候、禁止控制Player
		doingSetup = true;
		//LevelImage对象・LevelText对象的获取
		levelImage = GameObject.Find("LevelImage");
		levelText = GameObject.Find("LevelText").GetComponent<Text>();
		levelText.text = "Day " + level; //更新至最新的level
		levelImage.SetActive(true); //控制LebelImage激活用于显示

		Invoke("HideLevelImage", levelStartDelay); //2秒后调用HideLevelImage方法
												   //********** 修正结束 **********//

		// 每次读取游戏场景的时候，敌人的游戏对象会被清空，但是敌人的脚本实例还存留在enemies中
		// 我们每次读取新关卡的时候清空一下敌人脚本的实例
		enemies.Clear(); //Enemy的List(序列)初始化

		//BoardManager执行SetupScene方法
		boardScript.SetupScene(level);
	}

	//********** 修正开始 **********//
	private void HideLevelImage()
	{
		levelImage.SetActive(false); // 关闭LevelImage
		doingSetup = false; // 使Player可以被控制

		// 吐槽 感觉这样更好一点
		//doingSetup = levelImage.activeSelf;
	}
	//********** 修正结束 **********//

	public void GameOver()
	{

		//********** 修正开始 **********//
		// GameOver的信息
		levelText.text = "After " + level + " days, you starved.";
		levelImage.SetActive(true);
		//********** 修正结束 **********//

		//使GameManager无效
		enabled = false;
	}

	void Update()
	{
		//Player的回合或者Enemy敌人的行动时不执行更新Update
		//********** 修正开始 **********//
		//doingSetup=true的时候禁止Enemy的活动
		if (playersTurn || enemiesMoving || doingSetup)
		{
			//********** 修正结束 **********//
			return;
		}

		StartCoroutine(MoveEnemies());
	}

	public void AddEnemyToList(Enemy script)
	{
		enemies.Add(script);
	}

	// 敌人的回合 执行敌人的移动方法
	IEnumerator MoveEnemies()
	{
		enemiesMoving = true;
		yield return new WaitForSeconds(turnDelay);
		if (enemies.Count == 0)
		{
			// 为了防止玩家连续输入移动，等待玩家的移动动画结束，给敌人的回合增加一个延迟
			yield return new WaitForSeconds(turnDelay);
		}

		//执行Enemy数量的Enemy脚本的MoveEnemy
		for (int i = 0; i < enemies.Count; i++)
		{
			enemies[i].MoveEnemy();
			// 每一个敌人的移动耗时，为了让屏幕中看到敌人是一个接一个移动
			// 如果这里没有等待，就看到的是屏幕中所有敌人一起瞬移
			yield return new WaitForSeconds(enemies[i].moveTime);
		}

		playersTurn = true;
		enemiesMoving = false;
		// 建议 写成枚举型，而不要用多个bool来控制
		// 比如说
		// enum TrunType {
		//	PlayerTrun1
		//	EnemyWait
		//  PlayerTrun2
		//  EnemyTrun
		//  }
	}
}